let symbol = ['#', '(', '+', '-', '*', '/', ')'] // 存储操作符
let symbolPriority = {
  '#': 0,
  '(': 1,
  '+': 2,
  '-': 2,
  '*': 3,
  '/': 3,
  ')': 4
}
function operaSymbol (char, sym, res) {
  let lastChar = sym[sym.length - 1] // 取出栈顶的元素
  if (!lastChar) {
    // 如果栈顶的元素不存在 那就将这个char放入栈顶
    sym.push(char)
  }
  if (char === '(') {
    // 如果啥正括号
    sym.push(char) // 直接放入栈顶
  } else if (char === ')') {
    // 如果是反括号 就把栈中的操作符弹出栈 并将弹出的存入到表达式中 知道遇到正括号
    let currChar = sym.pop()
    while (sym && currChar !== '(') {
      res.push(currChar)
      currChar = sym.pop() // 继续不断的弹出
    }
  } else if (symbolPriority[char] > symbolPriority[lastChar]) {
    // 如果啥其他操作符 如果他的优先级比其他的优先级要搞 那就让其直接入栈
    sym.push(char)
  } else if (symbolPriority[char] < symbolPriority[lastChar]) {
    // 如果优先级不高 就一次弹出栈顶的操作符存入后缀表中,知道遇到一个栈顶优先级小于当前优先级的时候 或者说栈元素为(为止,保持当前栈顶元素不变,并将当前元素入栈
    while (lastChar && (symbolPriority[char] <= symbolPriority[lastChar])) {
      let currChar = sym.pop() // 弹出
      res.push(currChar) // 放入这个中
      lastChar = sym[sym.length - 1] // 修改这个最后的字符
    }
    sym.push(char)
  }
}
function toSuffixExpre (str) { // 传入一个字符串
  if (str[0] === '-') {
    str = '0' + str
  }
  let res = [] // 结果
  let sym = [] // 栈
  let substr = '' // 数字=>10的时候遍历会即为两个数字
  for (let i = 0; i < str.length; i++) {
    if (symbol.includes(str[i])) { // 如果是符号
      // substr && res.push(substr); // 如果这个存在 就把他放到这个里面
      res.push(substr); // 如果这个存在 就把他放到这个里面
      substr = '' // 修改原来的substr 代表着数字
      operaSymbol(str[i], sym, res) // 对操作符进行判断 传入的是当前的操作符 和栈 和表达式数组
    } else {
      substr += str[i] // 如果不是符号 就直接放入表达式中
    }
  }
  res.push(substr)
  while (sym.length > 0) {
    let currChar = sym.pop()
    res.push(currChar)
  }
  // let result = res.join(' ') // res存放逆波兰表达式
  return res // 最后输出的结果是逆波兰表达式
}
var test1 = '(2-3)*4+10/5'
let nibolan = toSuffixExpre(test1)
console.log(nibolan);
var calc = function (s1, s2, char) {
  switch (char) {
    case "+": return s1 + s2;
    case "-": return s1 - s2;
    case "*": return s1 * s2;
    case "/": return (s1 / s2) <= 0 ? Math.ceil(s1 / s2) : Math.floor(s1 / s2);
  }
}
var evalRPN = function (tokens) {
  let stack = [],
    len = tokens.length;
  let res = null;
  for (let i = 0; i < len; i++) {
    if (tokens[i] === "+"
      || tokens[i] === "-"
      || tokens[i] === "*"
      || tokens[i] === "/") {
      let s2 = stack.pop(),
        s1 = stack.pop();
      res = calc(s1 * 1, s2 * 1, tokens[i]);
      stack.push(res);
    } else {
      stack.push(tokens[i]);
    }
  }
  return stack.pop();
};

console.log(evalRPN(nibolan));